Chart
Present users with interactive graphical representations of data.
#Intro
The Chart
component is a tailored wrapper built for the Highcharts library within a React environment. It's designed to offer a seamless integration of Highcharts while incorporating customized features, improved accessibility, and enhanced usability.
#Key Features
- Customizations: The
Chart
component provides predefined customizations regarding colors, sizes, and themes to maintain consistency and visual appeal across charts. - Accessibility Improvements: Accessibility is a prime focus. The component ensures that charts are optimized for screen readers and other assistive technologies, making data visualization more inclusive.
- Enhanced Usability: With improved interaction elements and intuitive functionalities, the
Chart
component aims to enhance user experience and ease of navigation within the charts. - Highcharts Features: Developers have full access to all Highcharts features, allowing them to leverage the extensive capabilities of Highcharts to create sophisticated and detailed charts.
#Support and Troubleshooting
The Chart
component strives to ensure a seamless experience with Highcharts integrations. If you encounter any issues or discrepancies specific to the Chart
component that differ from the standard Highcharts behavior, please reach out to us for support. If the issue works as expected with Highcharts in its raw form, kindly let us know to address the compatibility concern.
#Examples
The examples below showcase the various kinds of charts suported by Highcharts, such as line charts, column charts, and more (coming soon). Click on the tabs to view the examples.
For general features and functionalities, please refer to the Miscellaneous section.
#Basic usage
<Chart
options={{
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
{...translations}
/>
#Usage with categories
<Chart
options={{
xAxis: {
categories: ["Apples", "Bananas", "Oranges", "Strawberries"],
tickInterval: 1,
},
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52],
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44],
},
],
}}
{...translations}
/>
#Usage with X axis showing time
<Chart
options={{
xAxis: {
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
series: [
{
type: "line",
name: "Series 1",
dashStyle: "ShortDot",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 10,
},
{
x: Date.UTC(2010, 1, 2),
y: 20,
},
{
x: Date.UTC(2010, 2, 3),
y: 30,
},
{
x: Date.UTC(2010, 3, 4),
y: 40,
},
{
x: Date.UTC(2010, 4, 5),
y: 50,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 20,
},
{
x: Date.UTC(2010, 1, 2),
y: 30,
},
{
x: Date.UTC(2010, 2, 3),
y: 40,
},
{
x: Date.UTC(2010, 3, 4),
y: 50,
},
{
x: Date.UTC(2010, 5, 5),
y: 60,
},
],
},
],
}}
{...translations}
/>
#Usage with multiple Y axes
<Chart
options={{
xAxis: [
{
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
],
yAxis: [{}, { opposite: true }],
series: [
{
type: "line",
name: "Series 1",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 10,
},
{
x: Date.UTC(2010, 1, 1),
y: 20,
},
{
x: Date.UTC(2010, 2, 1),
y: 30,
},
{
x: Date.UTC(2010, 3, 1),
y: 40,
},
{
x: Date.UTC(2010, 4, 1),
y: 50,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 20,
},
{
x: Date.UTC(2010, 1, 1),
y: 30,
},
{
x: Date.UTC(2010, 2, 1),
y: 40,
},
{
x: Date.UTC(2010, 3, 1),
y: 50,
},
{
x: Date.UTC(2010, 5, 1),
y: 60,
},
],
},
{
type: "line",
name: "Series 3",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 25,
},
{
x: Date.UTC(2010, 1, 1),
y: 50,
},
{
x: Date.UTC(2010, 2, 1),
y: 75,
},
{
x: Date.UTC(2010, 3, 1),
y: 90,
},
{
x: Date.UTC(2010, 5, 1),
y: 105,
},
],
yAxis: 1,
},
],
}}
{...translations}
/>
#Usage with several series
<Chart
options={{
series: [
{
type: "line",
name: "Series 1",
data: [1.12, 1.14, 1.13, 1.16, 1.18, 1.17, 1.15, 1.19, 1.2, 1.22].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [1.01, 1.05, 1.1, 1.09, 1.05, 1.02, 1.0, 1.01, 1.01, 1.02].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 3",
data: [0.9, 1.01, 1.02, 1.03, 1.02, 1.0, 0.98, 0.96, 0.95, 0.99].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 4",
data: [1.5, 1.6, 1.65, 1.7, 1.75, 1.78, 1.78, 1.79, 1.8, 1.8].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 5",
data: [1.4, 1.38, 1.35, 1.31, 1.3, 1.3, 1.29, 1.28, 1.3, 1.32].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 6",
data: [1.0, 1.1, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
{...translations}
/>
#Usage with Annotations
Annotations are designed to be easily adaptable to any backend. For that, you can map your own data structure to our Annotations interface which has the following definition:
type AnnotationItem = {
id: string | number;
date: Date;
comment: string;
createdBy: string;
visibility: string;
isFavorite: boolean;
visibleIn: string[];
username: string;
}
In addition, the Chart
component also provides properties for handling all basic annotation operations, such as creation (onCreateAnnotation
), update (onUpdateAnnotation
), and deletion (onDeleteAnnotation
).
In the example below, the API
object simulates the implementation of these methods and also provides a list of annotations according to the AnnotationItem
interface.
const chartDateOptions: DateOptions = {
locale: "en-us",
skipTimezoneReset: false,
};
const [annotationsData, setAnnotationsData] = useState<AnnotationItem[]>([]);
const [annotationsAreasVisibleIn, setAnnotationsAreasVisibleIn] = useState<
AnnotationAreasVisibleIn[]
>([]);
useEffect(() => {
let isDataFetchDone = true;
API.fetch().then((data) => isDataFetchDone && setAnnotationsData(data));
API.fetchAreasVisibleIn().then(
(areas) => isDataFetchDone && setAnnotationsAreasVisibleIn(areas)
);
return () => {
isDataFetchDone = false;
};
}, []);
return (
<Chart
options={{
xAxis: {
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
series: [
{
type: "line",
name: "Series 1",
data: [
{
x: Date.UTC(2022, 1, 1),
y: 20,
},
{
x: Date.UTC(2022, 2, 1),
y: 30,
},
{
x: Date.UTC(2022, 3, 1),
y: 40,
},
{
x: Date.UTC(2022, 4, 1),
y: 50,
},
{
x: Date.UTC(2022, 5, 1),
y: 30,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2022, 0, 1),
y: 20,
},
{
x: Date.UTC(2022, 1, 1),
y: 30,
},
{
x: Date.UTC(2022, 2, 1),
y: 40,
},
{
x: Date.UTC(2022, 3, 1),
y: 50,
},
{
x: Date.UTC(2022, 5, 1),
y: 60,
},
],
},
],
}}
{...translations}
showAnnotationButton
annotations={annotationsData}
chartPeriod={[new Date(2022, 0, 1), new Date(2022, 3, 1)]}
onUpdateAnnotation={async (data: Omit<Partial<AnnotationItem>, "createdBy">) => {
await API.update(data);
setAnnotationsData(await API.fetch());
}}
onCreateAnnotation={async (data: Omit<AnnotationItem, "id" | "createdBy">) => {
await API.create(data);
setAnnotationsData(await API.fetch());
}}
onDeleteAnnotation={async (id: string | number) => {
await API.delete(id);
setAnnotationsData(await API.fetch());
}}
chartDateOptions={chartDateOptions}
annotationAreasVisibleIn={annotationsAreasVisibleIn}
/>
);
#Miscellaneous
These examples showcase the various features and functionalities of the Chart
component that are not specific to any particular chart type. It includes features such as legends, tooltips, sizes, and more.
#Usage with reference lines
const { ColorRed, ColorTextStaticBody } = useDesignToken();
return (
<Chart
options={{
yAxis: {
plotLines: [
{
value: 70,
color: ColorRed,
width: 3,
dashStyle: "ShortDot",
label: {
text: "Limit (70)",
align: "right",
x: -5,
style: {
color: ColorTextStaticBody,
},
},
},
],
},
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [15, 13, 38, 42, 42, 47, 46, 51, 56].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
{...translations}
/>
);
#Usage with no legend
<Chart
options={{
plotOptions: {
series: {
showInLegend: false,
},
},
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
{...translations}
/>
#Usage with series hidden on load
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
selected: false,
},
],
}}
{...translations}
/>
#Usage with series not visible in the legends
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
showInLegend: false,
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
{...translations}
/>
#Usage with missing data
If all series contain empty data (undefined
, null
or NaN
) in a determined position, the row will not be displayed on the table visualization.
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, undefined, 52, 57, 56, 61].map((val, i) => {
return {
x: i,
y: val,
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, undefined, 49, 59, 65, 71].map((val, i) => {
return {
x: i,
y: val,
};
}),
},
],
}}
{...translations}
/>
#Usage with tooltip formatters
The header of the chart tooltip can be formatted using the optional property tooltipHeaderFormatter
with the values default
, named
, and keyed
.
The individual points of the chart tooltip can be formatted using the optional property tooltipPointFormatter
with the values default
, named
, and customValue
.
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: "Name for x: " + i.toString(),
customValue: "Custom value for x: " + i.toString() + " in series 1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: "Name for x: " + i.toString(),
customValue: "Custom value for x: " + i.toString() + " in series 2",
};
}),
},
],
}}
{...translations}
tooltipHeaderFormatter="named"
tooltipPointFormatter="customValue"
/>
#Visual
#Height
Use the height
property to adjust the chart size. The default height is medium
(310px
) and should be used in most cases. Use small
height when space is limited. Use large
or a custom value when the previous sizes are not suitable.
function BaseChart(props: { height: ChartProps["height"] }) {
return (
<>
<InlineText emphasis="medium">{props.height}</InlineText>
<br />
<Chart
height={props.height}
hideContextMenu
options={{
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: val.toString(),
};
}),
},
],
}}
{...translations}
/>
</>
);
}
return (
<>
<BaseChart height="small" />
<BaseChart height="medium" />
<BaseChart height="large" />
</>
);
#Usage with context menu changes
Use the hideContextMenu
property to remove the Context Menu gear icon. The default setting is to show the Context Menu. In addition, use the hideEnhancedContrastOption
property to remove the Enhanced contrast option from the Conext menu when that is visible. The default setting is to show the Enhanced Contrast option.
In the example below, the hideContextMenu
is disabled and the hideEnhancedContrastOption
is enabled.
<Chart
hideContextMenu={false}
hideEnhancedContrastOption
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
{...translations}
/>
#Usage with persistent legend state
Use the onToggleSeries
property to persist the legend state. The default setting is to not persist the legend state, which means that the legend state will be reset when the page is refreshed. The visibility state of each series is controlled by the visible
property of the series object.
const [series, setSeries] = useState<Highcharts.SeriesOptionsType[]>([
{
type: "column",
name: "Series 1",
visible: true,
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
visible: false,
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
]);
return (
<Chart
onToggleSeries={(seriesIndex, visible) => {
const newSeries = [...series];
newSeries[seriesIndex].visible = visible;
setSeries(newSeries);
console.log(
"Save series visibility to user preferences (e.g.: localStorage)",
seriesIndex,
visible
);
}}
options={{ series }}
{...translations}
/>
);
#Data updates
The Chart
component automatically updates the chart when the options
or height
properties change. This is useful when the chart data is updated dynamically or the layout changes and the chart needs to be redrawn.
const numberOfSeries = 2;
const seriesLength = 10;
const buildData = () => generateRandomData(numberOfSeries, seriesLength);
const [series, setSeries] = useState<number[][]>(buildData());
return (
<Content>
<Button onClick={() => setSeries(buildData())}>Generate series</Button>
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: series[0].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: series[1].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
{...translations}
/>
</Content>
);
#Usage with no data
In some real-world scenarios, the chart may not have any data to display. In this case, the chart frame and the table view will be empty.
<Chart
options={{
series: [],
}}
{...translations}
/>
#Properties
Property | Description | Defined | Value |
---|---|---|---|
optionsRequired | object Options for Highcharts chart | ||
screenReaderRegionLabelRequired | string Label for screen reader region | ||
screenReaderChartHeadingRequired | string Label for chart | ||
defaultChartTitleRequired | string Default chart label | ||
tableSummaryRequired | string Summary for the data displayed in the data table | ||
chartContainerLabelRequired | string Label for chart container | ||
legendItemRequired | string Legend item label | ||
chartTypesMapTypeDescriptionRequired | string Description for chart type map type | ||
chartTypesCombinationChartRequired | string Description for chart type combination chart | ||
chartTypesDefaultSingleRequired | string Description for chart type default single | ||
chartTypesDefaultMultipleRequired | string Description for chart type default multiple | ||
chartTypesSplineSingleRequired | string Description for chart type spline single | ||
chartTypesSplineMultipleRequired | string Description for chart type spline multiple | ||
chartTypesLineSingleRequired | string Description for chart type line single | ||
chartTypesLineMultipleRequired | string Description for chart type line multiple | ||
chartTypesColumnSingleRequired | string Description for chart type column single | ||
chartTypesColumnMultipleRequired | string Description for chart type column multiple | ||
chartTypesBarSingleRequired | string Description for chart type bar single | ||
chartTypesBarMultipleRequired | string Description for chart type bar multiple | ||
chartTypesPieSingleRequired | string Description for chart type pie single | ||
chartTypesPieMultipleRequired | string Description for chart type pie multiple | ||
xAxisDescriptionSingularRequired | string Description for x-axis singluar | ||
xAxisDescriptionPluralRequired | string Description for x-axis plural | ||
categoryColumnHeaderRequired | string Table column header for x-axis when the type is "category", "linear", or "logarithmic" | ||
datetimeColumnHeaderRequired | string Table column header for x-axis when the type is "datetime" | ||
yAxisDescriptionSingularRequired | string Description for y-axis singluar | ||
yAxisDescriptionPluralRequired | string Description for y-axis plural | ||
chartSeriesDefaultRequired | string Chart series summary default | ||
chartSeriesDefaultCombinationRequired | string Chart series summary default combination | ||
chartSeriesLineRequired | string Chart series summary line | ||
chartSeriesLineCombinationRequired | string Chart series summary line combination | ||
chartSeriesSplineRequired | string Chart series summary spline | ||
chartSeriesSplineCombinationRequired | string Chart series summary spline combination | ||
chartSeriesColumnRequired | string Chart series summary column | ||
chartSeriesColumnCombinationRequired | string Chart series summary column combination | ||
chartSeriesBarRequired | string Chart series summary bar | ||
chartSeriesBarCombinationRequired | string Chart series summary bar combination | ||
chartSeriesPieRequired | string Chart series summary pie | ||
chartSeriesScatterCombinationRequired | string Chart series summary pie combination | ||
chartSeriesMapCombinationRequired | string Chart series summary map combination | ||
chartSeriesMapbubbleCombinationRequired | string Chart series summary mapbubble combination | ||
xAxisDescriptionRequired | string Description of x-axis | ||
yAxisDescriptionRequired | string Description of y-axis | ||
contextMenuForLabelRequired | string Label for the context menu. It will be appended with the chart title. | ||
contextMenuEnhancedContrastLabelRequired | string Label for the enhanced contrast button in the context menu | ||
contextMenuEnhancedContrastTooltipRequired | string Tooltip content for the enhanced contrast button | ||
contextMenuTableViewLabelRequired | string Label for table view button in the context menu | ||
contextMenuTableViewTooltipRequired | string Tooltip content for the table view button | ||
showAnnotationButtonOptional | boolean Should show annotation button | ||
annotationsOptional | object[] Annotations array | ||
chartPeriodOptional | date[] Chart Period (for Annotations) | ||
onUpdateAnnotationOptional | function PUT call to update Annotation | ||
onCreateAnnotationOptional | function CREATE new Annotation | ||
onDeleteAnnotationOptional | function DELETE new Annotation | ||
chartDateOptionsOptional | object Date Options for the chart annotations | ||
annotationAreasVisibleInOptional | object[] Array of areas to allow annotations to be visible in | ||
heightOptional | | string | number Chart height (default medium, i.e. 310px) | ||
containerClassNameOptional | string CSS class for the Highcharts wrapper | ||
useHighchartsLegendOptional | boolean Use native Highcharts legend | ||
onToggleSeriesOptional | function Callback for toggling series visibility | ||
hideContextMenuOptional | boolean Hides the context menu icon | ||
hideEnhancedContrastOptionOptional | boolean Hides the enhanced contrast context option | ||
overflowableOptional | boolean Should overflow be allowed (if not, tooltip might be cut off) | ||
a11yModeOptional | boolean Enables enhanced contrast mode | ||
tooltipHeaderFormatterOptional | "default" | "keyed" | "named" Tooltip header formatters | ||
tooltipPointFormatterOptional | "customValue" | "default" | "named" Tooltip point formatters | ||
data-observe-keyOptional | string Unique string, used by external script e.g. for event tracking | ||
classNameOptional | string Custom className that's applied to the outermost element (only intended for special cases) | ||
styleOptional | object Style object to apply custom inline styles (only intended for special cases) |
#Guidelines
#Best practices
#Do not use when
#Accessibility
Explore detailed guidelines for this component: Accessibility Specifications